package com.hsmpay.mobile.service.brokerage.impl;

import com.hsmpay.common.service.impl.BaseServiceSupport;
import com.hsmpay.common.util.ClearMac;
import com.hsmpay.common.util.DateConvertUtil;
import com.hsmpay.common.util.NumberUtil;
import com.hsmpay.mobile.dao.brokerage.BrokEachOrderDao;
import com.hsmpay.mobile.dao.brokerage.BrokerDetailsOrderDao;
import com.hsmpay.mobile.dao.brokerage.BrokerageOrderDao;
import com.hsmpay.mobile.pojo.brokerage.BrokEachOrder;
import com.hsmpay.mobile.pojo.brokerage.BrokerDetailsOrder;
import com.hsmpay.mobile.pojo.brokerage.BrokerageOrder;
import com.hsmpay.mobile.pojo.organization.Organization;
import com.hsmpay.mobile.service.account.OrganizationService;
import com.hsmpay.mobile.service.brokerage.BrokerageOrderService;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 佣金服务接口 
 * 订单的意思  就是要快  先不重构了  怎样快怎样来
 */
@Service("brokerageOrderService")
public class BrokerageOrderServiceImpl extends BaseServiceSupport<BrokerageOrder, Long> implements BrokerageOrderService<BrokerageOrder, Long> {
	static Logger log = Logger.getLogger(BrokerageOrderServiceImpl.class);
	//佣金订单DAO
	@Resource(name="brokerageOrderDao")
	private BrokerageOrderDao<BrokerageOrder, Long> brokerageOrderDao;
	//机构DAO
	@Resource(name="organizationService")
	private OrganizationService<Organization,Long> organizationService;//机构服务类
	@Resource(name="brokEachOrderDao")
	private BrokEachOrderDao<BrokEachOrder, Long> brokEachOrderDao;
	//佣金订单DAO
	@Resource(name="brokerDetailsOrderDao")
	private BrokerDetailsOrderDao<BrokerDetailsOrder, Object> brokerDetailsOrderDao;

	/**
	 * 分组 统计 BrokEachOrder 生成佣金订单
	 * @param map
	 * @return
	 * @throws Exception
	 */
	public int generateBrokerageOrder(Map<String, Object> map)throws Exception{
		try {
			Date now = new Date();
			BrokerageOrder cb = null;
			BrokerDetailsOrder bdo = null;

			//分组 统计 BrokEachOrder总数 存入 info_BrokerageOrder 表
			List<BrokEachOrder> totalList = brokEachOrderDao.searchEachOGBOrgIdList(map);

			//负数佣金
			List<BrokerageOrder> negativeBoList = new ArrayList<BrokerageOrder>();
			
			//OEM结算佣金
			List<BrokerageOrder> oemBoList = new ArrayList<BrokerageOrder>();
			
			//不结算或暂停结算结算佣金
			List<BrokerageOrder> noOrPauseClearList = new ArrayList<BrokerageOrder>();
			
			Organization tempOrg = null;
			double revenueFee = 0.00;
			List<BrokerageOrder> bfBoList = null;
			
			for(BrokEachOrder beo : totalList){
				if(null == beo.getBrokerage()){//大pos 参数有可能为空
					continue;
				}
				
				cb = new BrokerageOrder();
				cb.setCreateDate(now);
				cb.setLongDate(now.getTime());
				cb.setClearStartDate((Date)map.get("startDate"));
				cb.setClearEndDate((Date)map.get("endDate"));
				
				cb.setOrganizationId(beo.getOrganizationId());//机构ID
				cb.setRoleId(null);//终端角色ID (为了兼容之前版本，暂时存null)
				cb.setTotalBrokerage(beo.getTotalBrokerage());//总佣金
				cb.setTotalTransMoney(beo.getTransMoney());//交易金额
				cb.setTotalFeeMoney(beo.getFee());//交易手续费
				cb.setTransMoney(NumberUtil.roundF2(beo.getBrokerage() * 0.94));//佣金 直接代扣百六的税点 发票寄回补结
				cb.setOrderTypeId(null);//类型 1收款 8提现 (为了兼容之前版本，暂时存null)
				
				//查询机构信息
				Organization organization = new Organization();
				organization.setId(beo.getOrganizationId());
				tempOrg = organizationService.searchEntity(organization);
				if(tempOrg.getType() > 1){
					cb.setBusinessType(2);//代理商佣金结算
				}else{
					cb.setBusinessType(1);//OEM佣金结算
				}
				cb.setUserName(tempOrg.getOrgCleaning().getCardholder());
				cb.setBankCard(tempOrg.getOrgCleaning().getBankCard());
				cb.setOpeningBank(tempOrg.getOrgCleaning().getOpeningBank());
				cb.setBranchesBank(tempOrg.getOrgCleaning().getBranchesBank());
				cb.setBBankProvince(tempOrg.getOrgCleaning().getbBankProvince());
				cb.setBBankCity(tempOrg.getOrgCleaning().getbBankCity());
				cb.setBranchesBankCode(tempOrg.getOrgCleaning().getBranchesBankCode());
				cb.setAccBankCode(tempOrg.getOrgCleaning().getAccBankCode());
				cb.setOrganizationName(tempOrg.getName());//下面 处理负数 有用到
				cb.setLayer(tempOrg.getLayer());//下面 处理负数 有用到
				cb.setBroClearType(tempOrg.getBroClearType());//结算类型 1、系统结算 2、代理商结算
				
				cb.setIsAssign(1);//已经分配佣金
				if(beo.getBrokerage() > 50000){
					revenueFee = Math.ceil(beo.getBrokerage()/50000)*0.30;
				}else{
					revenueFee = 0.30;
				}
				cb.setClearType(2);//三毛结算
				cb.setRevenueFee(revenueFee);
				
				
				if(cb.getTransMoney() < 0){
					cb.setStatus(6);//等待拨款
				}else{
					cb.setStatus(3);// 未结算
					cb.setInvoiceStatus(0);// 未收到发票
				}
				Double totalMoney = cb.getTransMoney();
				String bfboIds = "";
				if(cb.getStatus() == 3){
					bfBoList =  brokerageOrderDao.getOIdRoleIdLessMoneyList(cb.getOrganizationId(),cb.getRoleId(),"3",cb.getOrderTypeId(),50.0);//,4,6
					for(int i = 0 ;i < bfBoList.size() ; i++){
						BrokerageOrder bfbo = bfBoList.get(i);
						totalMoney += bfbo.getTransMoney();
						if(i == 0)  bfboIds += bfbo.getId(); else bfboIds += "," + bfbo.getId();
						brokerageOrderDao.updateBrokerageOrderByStatus(bfbo.getId(),5,"已经合并到周期["+ DateConvertUtil.dateString(cb.getClearStartDate(), "yyyy-MM-dd") + " — " + DateConvertUtil.dateString(cb.getClearEndDate(), "yyyy-MM-dd") +"] 一起结算");
					}
				}
				cb.setOrgbMoney(cb.getTransMoney());//保存本结算周期应得佣金
				cb.setTransMoney(totalMoney);
				cb.setOrgbIds(bfboIds);
				
				
				// 佣金为零直接将状态置为《完成结算
				if (cb.getTransMoney() == 0) {
					cb.setStatus(1);// 完成结算
					cb.setIsAssign(1);//已经分配佣金
					cb.setInvoiceStatus(1);// 已收到发票
				}
				
				String orgClearMac = ClearMac.getOrgClearMac(tempOrg.getBroStatus(), tempOrg.getOrgCleaning().getBankCard(), tempOrg.getOrgCleaning().getOpeningBank(), tempOrg.getOrgCleaning().getCardholder());
				
				//验证机构clearMac
				if(tempOrg.getClearMac() != null && !orgClearMac.equals(tempOrg.getClearMac())){
					cb.setStatus(11);//存在违法嫌疑
				}
				
				//如果佣金结算类型 不为代理结算
				if(tempOrg.getBroStatus() == 2){// 暂停结算
					cb.setStatus(7);
				}else if (tempOrg.getBroStatus() == 3) {//不结算
					cb.setStatus(5);
				}
				
				//生成佣金订单clearMac
				cb.setClearMac(ClearMac.getBroClearMac(cb.getOrganizationId(), cb.getTotalBrokerage(), cb.getTransMoney(), cb.getBankCard(), cb.getOpeningBank(), cb.getUserName()));
				//添加
				Long boId = brokerageOrderDao.insertEntity(cb);				
				if(cb.getTransMoney() < 0){//如果为负数  保存该记录
					cb.setId(boId);
					negativeBoList.add(cb);
				}
				
				if(tempOrg.getBroClearType() == 2){//如果是OEM结算
					cb.setId(boId);
					oemBoList.add(cb);
				}
				
				//如果佣金结算类型为不结算或暂停结算
				if(tempOrg.getBroStatus() == 2 || tempOrg.getBroStatus() == 3){// 暂停结算或不结算
					cb.setId(boId);
					noOrPauseClearList.add(cb);
				}
				
			}
			
			//处理负数
			if(negativeBoList.size() > 0){
				negativeBo(negativeBoList);
			}
			
			//处理代理商结算的佣金
			if(oemBoList.size() > 0){
				oemClearing(oemBoList);
			}
			
			//处理不结算或暂停结算的佣金
			if(noOrPauseClearList.size() > 0){
				noOrPauseClear(noOrPauseClearList);
			}
			
			//分组 统计 BrokEachOrder 存入 info_Brok_detailsOrder 表
			List<BrokEachOrder> beoList = brokEachOrderDao.searchEachOGBOrgIdRoleIdList(map);
			
			Organization tempOrg2 = null;
			
			for(BrokEachOrder beo : beoList){
				if(null == beo.getBrokerage()){//大pos 参数有可能为空
					continue;
				}
				
				bdo = new BrokerDetailsOrder();
				//cb.setBusinessType(1);//OEM佣金结算
				bdo.setCreateDate(now);
				bdo.setLongDate(now.getTime());
				bdo.setClearStartDate((Date)map.get("startDate"));
				bdo.setClearEndDate((Date)map.get("endDate"));
				
				bdo.setOrganizationId(beo.getOrganizationId());//机构ID
				bdo.setRoleId(beo.getRoleId());//终端角色ID
				bdo.setTotalBrokerage(beo.getTotalBrokerage());//总佣金
				bdo.setTotalTransMoney(beo.getTransMoney());//交易金额
				bdo.setTotalFeeMoney(beo.getFee());//交易手续费
				bdo.setTransMoney(NumberUtil.roundF2(beo.getBrokerage() * 0.94));//佣金 直接代扣百六税点 发票寄回补结
				bdo.setOrderTypeId(beo.getOrderTypeId());//类型 1收款 8提现
				
				//查询机构信息
                Organization organization = new Organization();
                organization.setId(beo.getOrganizationId());
				tempOrg2 = organizationService.searchEntity(organization);
				if(tempOrg2.getType() > 1){
					bdo.setBusinessType(2);//代理商佣金结算
				}else{
					bdo.setBusinessType(1);//OEM佣金结算
				}
				
				//添加
				brokerDetailsOrderDao.insertEntity(bdo);
                //更新机构佣金订单结算状态
                Map updateParam = new HashMap();
                updateParam.put("organizationId",beo.getOrganizationId());
                updateParam.put("clearStatus",1);
                brokEachOrderDao.updateBrokEachOrderClearStatusByOrg(updateParam);
			}
		}catch(Exception e){
			e.printStackTrace();
			throw e;
		}
		
		return 1;
	}

	/**
	 * 处理不结算或暂停结算的佣金
	 * @throws Exception
	 */
	private void noOrPauseClear(List<BrokerageOrder> noOrPauseClearList)throws Exception{
		//遍历
		for(BrokerageOrder bo : noOrPauseClearList){
			if(bo.getStatus() == 7){//暂停结算

				//修改所有子集    7暂停结算
				int flag = brokerageOrderDao.updateBOStatusByLayer(7, "因父级代理商 ["+bo.getOrganizationName()+"] 设置为暂停结算！", null, bo.getLayer(),bo.getRoleId(),bo.getClearStartDate(),bo.getClearEndDate(),bo.getOrderTypeId());
				log.debug("修改所有子集暂停结算flag:"+flag);

			}else if (bo.getStatus() == 5) {//不结算

				//修改所有子集    5不结算
				int flag = brokerageOrderDao.updateBOStatusByLayer(5, "因父级代理商 ["+bo.getOrganizationName()+"] 设置为不结算！", null, bo.getLayer(),bo.getRoleId(),bo.getClearStartDate(),bo.getClearEndDate(),bo.getOrderTypeId());
				log.debug("修改所有子集不结算flag:"+flag);

			}

		}

	}

	/**
	 * 处理OEM结算的佣金
	 * @throws Exception
	 */
	private void oemClearing(List<BrokerageOrder> oemBoList)throws Exception{
		//遍历
		for(BrokerageOrder bo : oemBoList){
			BrokerageOrder cb = new BrokerageOrder();
			cb.setId(bo.getId());
			
			
			//查询该层下面的机构佣金总和（包括自己）
			double totalMoney = brokerageOrderDao.getTotalMoneyByLayer(bo.getLayer(),bo.getRoleId(),bo.getClearStartDate(),bo.getClearEndDate(),bo.getOrderTypeId());
			
			cb.setTransMoney(totalMoney);//修改该机构的所得佣金
			if(bo.getStatus() == 8 ||bo.getStatus() == 6){
				cb.setStatus(3);
			}
			
			//生成新的佣金订单clearMac
			cb.setClearMac(ClearMac.getBroClearMac(bo.getOrganizationId(), bo.getTotalBrokerage(), cb.getTransMoney(), bo.getBankCard(), bo.getOpeningBank(), bo.getUserName()));
			
			brokerageOrderDao.updateEntity(cb);//修改佣金
			
			//修改所有子集结算状态（结算关闭，等待OEM结算）
			int flag = brokerageOrderDao.updateBOStatusByLayer(9, "由父级代理商 ["+bo.getOrganizationName()+"] 结算！", null, bo.getLayer(),bo.getRoleId(),bo.getClearStartDate(),bo.getClearEndDate(),bo.getOrderTypeId());
			log.debug("修改所有子集等待OEM结算flag:"+flag);
			
			//修改所有子集结算机构
			int broClearOrg = brokerageOrderDao.updateBroClearOrgByLayer( bo.getOrganizationId(),bo.getLayer(),bo.getRoleId(),bo.getClearStartDate(),bo.getClearEndDate(),bo.getOrderTypeId());
			log.debug("修改所有子集等待OEM结算broClearOrg:"+broClearOrg);
			
		}
		
	}
	
	/**
	 * 处理负数订单
	 * @throws Exception
	 */
	private void negativeBo(List<BrokerageOrder> negativeBoList)throws Exception{
		//遍历所有负数佣金
		for(BrokerageOrder bo : negativeBoList){
			//修改所有子集  3未付款状态的订单  为  4等待父级拨款
			int flag = brokerageOrderDao.updateBOStatusByLayer(4, "等待父级代理商 ["+bo.getOrganizationName()+"] 拨款！", 3, bo.getLayer(),bo.getRoleId(),bo.getClearStartDate(),bo.getClearEndDate(),bo.getOrderTypeId());
			log.debug("修改所有子集flag:"+flag);
			
			//查询该层下面的机构佣金总和（包括自己）
			double totalMoney = brokerageOrderDao.getTotalMoneyByLayer(bo.getLayer(),bo.getRoleId(),bo.getClearStartDate(),bo.getClearEndDate(),bo.getOrderTypeId());
			
			if(totalMoney < 0){
				//修改直属父集  3未付款状态的订单  为  8等待直属子级拨款
				int flag2 = brokerageOrderDao.updateBOStatusByOrganizationId(8, "等待直属子级代理商 ["+bo.getOrganizationName()+"] 拨款！", 3, bo.getOrganizationId(),bo.getRoleId(),bo.getClearStartDate(),bo.getClearEndDate(),bo.getOrderTypeId());
				log.debug("修改直属父集flag:"+flag2);
			}
			
		}
	}
}
